namespace Core
{
    using System;
    using System.IO;
    using System.Text;
    using Contracts.Interfaces;

    /// <summary>
    /// Text formatted fitting exporter class
    /// </summary>
    public sealed class TextFittingExporter : IFittingExporter
    {
        /// <summary>
        /// Export a fitting instance to a string representation
        /// </summary>
        /// <param name="fitting">An instance of IFitting</param>
        /// <returns>A string representation of the IFitting instance or null</returns>
        public string Export(IFitting fitting)
        {
            if (fitting == null) return null;
            var sb = new StringBuilder();
            Export(fitting, sb);
            return sb.ToString();
        }

        /// <summary>
        /// Export a fitting instance to a string representation
        /// </summary>
        /// <param name="fitting">An instance of IFitting</param>
        /// <param name="stringBuilder">A StrinBuilder instance to use</param>
        public void Export(IFitting fitting, StringBuilder stringBuilder)
        {
            if (fitting == null || stringBuilder ==null) return;
            stringBuilder.AppendFormat("[{0}, {1}]", fitting.Robot.Name, fitting.Name);

            stringBuilder.AppendLine("\r\n");
            foreach (var module in fitting.Robot.ChassisModules)
                AppendModule(module, stringBuilder);

            stringBuilder.AppendLine();
            foreach (var module in fitting.Robot.HeadModules)
                AppendModule(module, stringBuilder);

            stringBuilder.AppendLine();
            foreach (var module in fitting.Robot.LegModules)
                AppendModule(module, stringBuilder);
        }

        /// <summary>
        /// Export a fitting instance to a stream
        /// </summary>
        /// <param name="fitting">An IFitting instance</param>
        /// <param name="stream">A stream</param>
        public void Export(IFitting fitting, Stream stream)
        {
            Export(fitting, stream, Encoding.UTF8);
        }

        /// <summary>
        /// Export a fitting instance to a stream
        /// </summary>
        /// <param name="fitting">An IFitting instance</param>
        /// <param name="stream">A stream</param>
        /// <param name="encoding">The Encoding to use</param>
        public void Export(IFitting fitting, Stream stream, Encoding encoding)
        {
            if (fitting == null || stream == null || !stream.CanWrite) return;
            
            var sb = new StringBuilder();
            Export(fitting, sb);

            var buffer = encoding.GetBytes(sb.ToString());
            stream.Write(buffer, 0, buffer.Length);
        }

        private static void AppendModule(IModule module, StringBuilder stringBuilder)
        {
            stringBuilder.AppendFormat("{0}{1}\r\n", 
                module.Name, 
                module.HasAmmunitionsLoaded ? String.Format(", {0}", module.Ammunitions.Name) : null);
        }
    }
}